package com.service;


import com.dto.CarrierMonitorDTO;
import com.dto.CarrierMonitorReqDTO;
import com.dto.PageResDTO;
import com.util.ElasticSearchUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 *
 * </p>
 *
 * @author zhangqing
 * @since 2021/2/2
 */
@Service
@Slf4j
public class GisServiceImpl implements GisService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 根据索引查数据，然后根据name分组，返回集合
     *
     * @param dto
     * @return
     */
    @Override
    public PageResDTO<CarrierMonitorDTO> carrierMonitor(CarrierMonitorReqDTO dto) {

        //添加多索引
        String[] indexString = this.addIndex(dto);
//
//        //添加查询
        BoolQueryBuilder boolQueryBuilder = this.getQuery(dto);
//
        //分组时间间隔来统计 返回一组数据
        AggregationBuilder agg = AggregationBuilders.terms("name")

                .field("name");
        AggregationBuilder agg2 = AggregationBuilders
                .topHits("carrier")
                .fetchSource(new String[]{"id", "name", "type", "isMove", "gmtCreate", "addr","remark"}, null)
                .size(1);
        agg.subAggregation(agg2);


        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.from(dto.getPage());
        sourceBuilder.from(dto.getSize());
        sourceBuilder.aggregation(agg);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        SearchRequest searchRequest = new SearchRequest(indexString,sourceBuilder);

        try {
            log.info(sourceBuilder.toString());
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            return ElasticSearchUtil.getTopHitsAggrsPage(search.getAggregations(),dto.getPage(),dto.getSize());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());

        }
    }

    /**
     * 添加查询
     *
     * @param dto
     * @return
     */
    private BoolQueryBuilder getQuery(CarrierMonitorReqDTO dto) {
        Map<String, String> map = new HashMap<>();
        map.put("id", dto.getCode());
        map.put("name", dto.getName());
        BoolQueryBuilder queryBuilder = ElasticSearchUtil.getQueryBuilder(map, null, null, null);
        return queryBuilder;

    }


    /**
     * 添加索上
     *
     * @param dto
     * @return
     */
    private String[] addIndex(CarrierMonitorReqDTO dto) {
        List<String> list = new ArrayList<>();
//        CarrierTypePageVm vm = new CarrierTypePageVm(1, 10000, dto.getId());
//
//        Optional<IPage<CarrierTypeDTO>> dtoList = carrierTypeService.getDTOList(vm);
//        IPage<CarrierTypeDTO> carrierTypeDTOIPage = dtoList.get();
//        if (carrierTypeDTOIPage == null) {
//            return null;
//        }
//        List<CarrierTypeDTO> records = carrierTypeDTOIPage.getRecords();
//        if (CollectionUtils.isEmpty(records)) {
//            return null;
//        }
//        for (CarrierTypeDTO record : records) {
//            if (record == null || StringUtils.isEmpty(record.getId())) {
//                continue;
//            }
//            String esIndex = carrierTypeService.getESIndexById(record.getId());
//            if (StringUtils.isEmpty(esIndex)) {
//                continue;
//            }
//            list.add(esIndex);
//        }

        return list.toArray(new String[list.size()]);


    }

    @Override
    public List<CarrierMonitorDTO.CarrierTravle> carrierTravleList(String id,Long start, Long end, String code, Integer minite) {
        CarrierMonitorReqDTO dto  = new CarrierMonitorReqDTO();
        dto.setId(id);
        String[] index = this.addIndex(dto);
       dto.setId(code);
        BoolQueryBuilder query = this.getQuery(dto);
        AggregationBuilder agg = AggregationBuilders.dateHistogram("gmtCreate")
                .interval(minite)
                .field("gmtCreate");
        AggregationBuilder agg2 = AggregationBuilders
                .topHits("carrier")
                .sort("gmtCreate", SortOrder.DESC)
                .fetchSource(new String[]{"gmtCreate", "latitude", "longitude"}, null)
                .size(1);
        agg.subAggregation(agg2);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(query);
        sourceBuilder.from(dto.getPage());
        sourceBuilder.from(dto.getSize());
        sourceBuilder.aggregation(agg);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        SearchRequest searchRequest = new SearchRequest(index,sourceBuilder);
        try {


        log.info(sourceBuilder.toString());
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        return  ElasticSearchUtil.getTopHitsAggrsList(search.getAggregations());
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
